/**
 * Copyright (C) 2010 Cloudfarming <info@cloudfarming.nl>
 *
 * Licensed under the Eclipse Public License - v 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package nl.cloudfarming.client.geoviewer.jxmap.map;

import com.vividsolutions.jts.geom.Geometry;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import nl.cloudfarming.client.geoviewer.Layer;
import nl.cloudfarming.client.geoviewer.LayerObject;
import nl.cloudfarming.client.geoviewer.jxmap.render.GeometryRenderer;
import nl.cloudfarming.client.geoviewer.jxmap.render.GeometryRendererFactory;
import nl.cloudfarming.client.model.BeanNotFoundException;
import nl.cloudfarming.client.util.GeometryUtil;
import org.jdesktop.swingx.JXMapViewer;
import org.jdesktop.swingx.mapviewer.GeoPosition;
import org.netbeans.api.visual.model.ObjectScene;
import org.netbeans.api.visual.model.ObjectState;
import org.netbeans.api.visual.widget.Widget;
import org.openide.util.Exceptions;

/**
 * An ItemWidget is a object on the map which is used for interaction from
 * the user with a dynamic object on the map (a {@link LayerItem}).
 * Someone can see a tooltip for a dynamic object and can use a context menu
 * (right mouse click on an object).
 * 
 * @author Maarten Hollenga
 */
public class LayerObjectWidget extends Widget {

    private static final int ICON_SIZE = 20;
    private String id;
    private final JXMapViewer mapViewer;
    private final LayerObject layerObject;
    private final Layer layer;
    private final RootMapPanelController controller;


    public void setId(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }

    /**
     * Initialize the widget for a dynamic object on the specified location
     * with a tooltip and a context menu.
     * 
     * @param scene A class that keeps associations between widgets and the 
     * objects that model them
     * @param layerItem The dynamic object on the map
     * @param tooltiptext The text to display at the tooltip
     * @param explorerManager node explorer manager
     */
    public LayerObjectWidget(final ObjectScene scene, LayerObject layerObject, Layer layer, RootMapPanelController controller) {
        super(scene);
        this.layer = layer;
        this.controller = controller;
        this.mapViewer = controller.getViewer();
        this.layerObject = layerObject;
        this.id = layerObject.getKey();
        setPreferredSize(new Dimension(ICON_SIZE, ICON_SIZE));
        setToolTipText(layerObject.getTooltipText());
        setForeground(this.layer.getPalette().getColorForValue(layerObject.getKeyAttributeValue()));
    }

    @Override
    protected void paintWidget() {
        //
        // get the renderer for the geometry in the layer object and render the geometry
        //
        GeometryRenderer renderer = GeometryRendererFactory.getRenderer(layerObject.getGeometry());
        getGraphics().setColor(getForeground());

        if (!layer.isInterActive()) {
            getGraphics().setColor(this.layer.getPalette().getColorForValue(layerObject.getKeyAttributeValue()));
        }
        Rectangle clientArea = renderer.paint(layerObject.getGeometry(), this.mapViewer, getGraphics(), getState().isSelected());
        clientArea = (clientArea != null) ? clientArea : super.calculateClientArea();

        setPreferredBounds(clientArea);
    }

    @Override
    protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
        //
        // only execute state conditional painting for active layers
        // and if the map panel is active
        //
        if (controller.isActive() && this.layer.isInterActive()) {
            if (!getForeground().equals(this.layer.getPalette().getColorForState(state))) {
                setForeground(this.layer.getPalette().getColorForState(state));
            }
            //
            // add node to the selection
            //
            if (!previousState.isSelected() && state.isSelected()) {
                try {
                    layer.getDataProvider().addBeanToSelection(layerObject.getObject());
                } catch (BeanNotFoundException ex) {
                    Exceptions.printStackTrace(ex);
                }
            }
            //
            // remove node from the selection
            //
            if (previousState.isSelected() && !state.isSelected()) {
                try {
                    layer.getDataProvider().removeBeanFromSelection(layerObject.getObject());
                } catch (BeanNotFoundException ex) {
                    Exceptions.printStackTrace(ex);
                }
            }
        }
    }

    @Override
    public boolean isHitAt(Point localLocation) {
        if (isVisible() && getBounds().contains(localLocation)) {

            Geometry geo = layerObject.getGeometry();
            // TODO: put in util
            Rectangle viewportBounds = mapViewer.getViewportBounds();

            int mapX = (int) (viewportBounds.getX() + localLocation.getX());

            int mapY = (int) (viewportBounds.getY() + localLocation.getY());
            Point2D newPoint = new Point(mapX, mapY);

            GeoPosition pos = mapViewer.getTileFactory().pixelToGeo(newPoint, mapViewer.getZoom());

            com.vividsolutions.jts.geom.Point pnt = GeometryUtil.getPoint(pos.getLongitude(), pos.getLatitude());
            return geo.intersects(pnt);

        } else {
            return false;
        }
    }
    /*
    
    private class PositionEditor implements TextFieldInplaceEditor {
    
    public boolean isEnabled(Widget widget) {
    return true;
    }
    
    public String getText(Widget widget) {
    return ((PointWidget) widget).getPositionString();
    }
    
    public void setText(Widget widget, String text) {
    ((PointWidget) widget).setPositionString(text);
    //            ((PointWidget) widget).setLabel(text);
    }
    }
    
    private class SomeAction extends AbstractAction{
    
    public SomeAction() {
    putValue(NAME,"some action");
    }
    
    
    
    @Override
    public void actionPerformed(ActionEvent e) {
    throw new UnsupportedOperationException("Not supported yet.");
    }
    
    }
     * 
     */
}
